package com.chandon.juc.thread_communication.AddStringsToList;

import java.util.ArrayList;
import java.util.List;

/**
 * 描述
 *
 * @author Dong
 */

public class UseWaitAndNotify {

	/**
	 * ArrayList是线程不安全的，当元素添加进去以后，还未进行更新size，就会出现问题。
	 * 可以使用线程安全的容器，如：
	 * Collections.synchronizedList(new ArrayList<>(10));
	 * 或将add方法与size方法封装成线程安全的。
	 * <p>
	 * 疑问：volatitle修饰的list是引用，没有修饰到内部的值size，为何起作用了。
	 * 猜测：被volatile关键字修饰的对象作为类变量或实例变量时，其对象中携带的类变量和实例变量也相当于被volatile关键字修饰了
	 */
	public static volatile List<String> list = new ArrayList<>(10);

	public static volatile boolean start = false;
	static final Object lock = new Object();

	/**
	 * 2. 使用wait()与notify()
	 */

	public static void waitAndNotify() {

		new Thread(() -> {
			synchronized (lock) {
				for (int i = 0; i < 10; i++) {
					list.add("abc");
					System.out.println(list.size());
					try {
						if (list.size() == 4) {
							System.out.println("线程B要启动了");
							lock.notify();
							lock.wait();
						}
						lock.notify();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}

				}
			}

		}).start();

		new Thread(() -> {
			synchronized (lock) {
				if (list.size() != 4) {
					try {
						lock.wait();
						lock.notify();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				lock.notify();

				System.out.println("thread B 启动了,list.size:" + list.size());
			}

		}).start();


	}

}
